/*
 * File:   Forma.cpp
 * Author: werty
 *
 * Created on 28 kwiecień 2011, 16:42
 */

//#include <qt4/QtGui/qradiobutton.h>
//#include <qt4/QtGui/qbuttongroup.h>
#include <QtGui/QMessageBox>


#include "Forma.h"

class CurveData : public QwtArraySeriesData<QPointF> {
public:

    CurveData() {
    }

    virtual QRectF boundingRect() const {
        if (d_boundingRect.width() < 0.0)
            d_boundingRect = qwtBoundingRect(*this);

        return d_boundingRect;
    }

    inline void append(const QPointF &point) {
        d_samples += point;
    }

    void clear() {
        d_samples.clear();
        d_samples.squeeze();
        d_boundingRect = QRectF(0.0, 0.0, -1.0, -1.0);
    }
};

Forma::Forma() {


    flaga_bledu = false;


    widget.setupUi(this);
    //resize(800, 1000);

    createActions();
    createMenus();


    //    int row = widget.lista_funkcji->rowCount();
    //    widget.lista_funkcji->insertRow(row);
    //    QTableWidgetItem *item0 = new QTableWidgetItem;
    //    QTableWidgetItem *item1 = new QTableWidgetItem;
    //    QTableWidgetItem *item2 = new QTableWidgetItem;
    //    //    // item0->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
    //    widget.lista_funkcji->setItem(row, 0, item0);
    //    widget.lista_funkcji->setItem(row, 1, item1);
    //    widget.lista_funkcji->setItem(row, 2, item2);
    //
    //    widget.lista_funkcji->resizeColumnToContents(0);
    widget.lista_funkcji->horizontalHeader()->setStretchLastSection(true);
    widget.lista_funkcji->setColumnWidth(0, 295);
    widget.lista_funkcji->setColumnWidth(1, 40);
    widget.lista_funkcji->setColumnWidth(2, 40);
    Dodaj_funkcje();
    Dodaj_funkcje();

    widget.lista_funkcji->item(0, 0)->setText(QString("(x1+50)^2+x2^2"));
    widget.lista_funkcji->item(1, 0)->setText(QString("(x1-50)^2+x2^2"));

    widget.lista_zmiennych->horizontalHeader()->setStretchLastSection(true);
    widget.lista_zmiennych->setColumnWidth(0, 215);
    widget.lista_zmiennych->setColumnWidth(1, 80);
    widget.lista_zmiennych->setColumnWidth(2, 80);

    widget.lista_ograniczen->horizontalHeader()->setStretchLastSection(true);
    widget.lista_ograniczen->setColumnWidth(0, 165);
    widget.lista_ograniczen->setColumnWidth(1, 45);
    widget.lista_ograniczen->setColumnWidth(2, 165);

    //widget.plot=new Plot();

    plot3d = new Plot();

    plot3d->setParent(widget.Plot3D);

    // mu::ParserInt int_parser;

    //   try {

    //#ifdef MUP_EXAMPLE_INT_PARSER
    //        int_parser.SetExpr(sLine);
    //        mu::console() << int_parser.Eval() << "\n";
    //        mu::console() << int_parser.Eval() << "\n";
    //#elif defined MUP_EXAMPLE_COMPLEX_PARSER
    //        cmplx_parser.SetExpr(sLine);
    //        mu::console() << cmplx_parser.Eval() << "\n";
    //#else
    //
    //
    //
    //        plot3d->rosenbrock->parser.SetExpr("log((1 - x)*(1 - x) + 100 * (y - x * x)*(y - x * x)) / 8");
    //
    //
    //
    //#endif
    //    } catch (mu::Parser::exception_type &e) {
    //        mu::console() << _T("\nError:\n");
    //        mu::console() << _T("------\n");
    //        mu::console() << _T("Message:     ") << e.GetMsg() << _T("\n");
    //        mu::console() << _T("Expression:  \"") << e.GetExpr() << _T("\"\n");
    //        mu::console() << _T("Token:       \"") << e.GetToken() << _T("\"\n");
    //        mu::console() << _T("Position:    ") << (int) e.GetPos() << _T("\n");
    //        mu::console() << _T("Errc:        ") << std::dec << e.GetCode() << _T("\n");
    //    }




    // Dot dot=Dot(0.007,0.5);

    //  Dot* dot = (Dot*)plot.setPlotStyle(Dot(0.007,false));

    // plot.addEnrichment(Dot(0.007,false));
    //    widget.lista_funkcji= new QTableWidget(0, 4);
    //    widget.lista_funkcji->setHorizontalHeaderLabels(QStringList() << tr("Działanie")
    //                                                   << tr("Priorytet")
    //                                                   << tr("Parametry")
    //                                                   << tr("Kolor")
    //                                                   );
    connect(widget.Rysuj, SIGNAL(clicked()), this, SLOT(Rysuj()));
    connect(widget.Iteruj, SIGNAL(clicked()), this, SLOT(Iteruj()));
    connect(widget.Funkcje, SIGNAL(currentIndexChanged(int)), this, SLOT(Zmiana_funkcji()));
    connect(widget.horizontalScrollBar, SIGNAL(sliderMoved(int)), this, SLOT(Suwak_poziomy()));
    connect(widget.verticalScrollBar, SIGNAL(sliderMoved(int)), this, SLOT(Suwak_pionowy()));
    connect(widget.checkBox_2, SIGNAL(stateChanged(int)), this, SLOT(Cube()));
    connect(widget.Resetuj, SIGNAL(clicked()), this, SLOT(Resetuj()));
    connect(widget.Wireframe, SIGNAL(clicked()), this, SLOT(Wireframe()));

    connect(widget.usun_funkcje, SIGNAL(clicked()), this, SLOT(Usun_funkcje()));
    connect(widget.dodaj_funkcje, SIGNAL(clicked()), this, SLOT(Dodaj_funkcje()));
    connect(widget.zaladuj_funkcje, SIGNAL(clicked()), this, SLOT(Dodaj_wszystkie_funkcje()));

    connect(widget.usun_ograniczenie, SIGNAL(clicked()), this, SLOT(Usun_ograniczenie()));
    connect(widget.dodaj_ograniczenie, SIGNAL(clicked()), this, SLOT(Dodaj_ograniczenie()));
    connect(widget.zaladuj_ograniczenia, SIGNAL(clicked()), this, SLOT(Dodaj_wszystkie_ograniczenia()));
    connect(widget.zaladuj_zakresy_zmiennych, SIGNAL(clicked()), this, SLOT(Dodaj_zakresy_zmiennych()));


    connect(widget.bInicjalizuj, SIGNAL(clicked()), this, SLOT(Inicjalizuj()));
    connect(widget.bIterujRaz, SIGNAL(clicked()), this, SLOT(Iteruj_raz()));


    plot3d->resize(600, 570);


    plot2d = new QwtPlot(QwtText("Two Curves"), (QWidget*) widget.Plot2D);
    plot2d->setFixedSize(500, 500);
    // add curves
    curve1 = new QwtPlotCurve("Curve 1");
    curve2 = new QwtPlotCurve("Curve 2");


    points_nondom = new QwtPlotCurve("Test Curve");
    points_nondom->setStyle(QwtPlotCurve::NoCurve);
    points_nondom->setData(new CurveData());

    points_nondom->setSymbol(new QwtSymbol(QwtSymbol::XCross,
            Qt::NoBrush, QPen(Qt::blue), QSize(4, 4)));

    points_nondom->attach(plot2d);



    points_dom = new QwtPlotCurve("Test Curve");
    points_dom->setStyle(QwtPlotCurve::NoCurve);
    points_dom->setData(new CurveData());

    points_dom->setSymbol(new QwtSymbol(QwtSymbol::XCross,
            Qt::NoBrush, QPen(Qt::red), QSize(4, 4)));

    points_dom->attach(plot2d);

    d_directPainter = new QwtPlotDirectPainter(plot2d);
    // copy the data into the curves
    //curve1->setRawSamples();
    //  curve2->setData(...);

    plot2d->setAxisAutoScale(plot2d->xBottom, true);
    plot2d->setAxisAutoScale(plot2d->yLeft, true);
    curve1->attach(plot2d);
    curve2->attach(plot2d);

    // finally, refresh the plot
    plot2d->replot();


    Zaladuj_wzor(widget.Wzor_PSO, "wzor_pso.mml");
    Zaladuj_wzor(widget.Wzor_c1, "wzor_c1.mml");
    Zaladuj_wzor(widget.Wzor_c2, "wzor_c2.mml");
    Zaladuj_wzor(widget.Wzor_w, "wzor_w.mml");
    Zaladuj_wzor(widget.Wzor_czi, "wzor_czi.mml");

    widget.czy_maksimum->setChecked(true);

    //  Rysuj();

}

Forma::~Forma() {
}

void Forma::Zaladuj_wzor(QWidget * parent, QString path) {
    QtMmlWidget* m_mml_widget = new QtMmlWidget(parent);

    //QString path="example.mml";


    QFile file(path);
    if (!file.open(QIODevice::ReadOnly)) {
        showWarning("File error: Could not open \""
                + path
                + "\": " + file.errorString());
        return;
    }

    QTextStream stream(&file);
    //    stream.setEncoding(QTextStream::UnicodeUTF8);
    QString text = stream.readAll();
    file.close();






    QString error_msg;
    int error_line, error_column;
    bool result = m_mml_widget->setContent(text, &error_msg, &error_line,
            &error_column);

    if (!result) {
        showWarning("Parse error: line " + QString::number(error_line)
                + ", col " + QString::number(error_column)
                + ": " + error_msg);

    }



}

void Forma::Rysuj() {

    plot3d->rosenbrock->setDomain(
            QVariant(widget.xmin->text()).toFloat(NULL),
            QVariant(widget.xmax->text()).toFloat(NULL),
            QVariant(widget.ymin->text()).toFloat(NULL),
            QVariant(widget.ymax->text()).toFloat(NULL));

    // plot->rosenbrock->setMinZ(widget.fmin->text().toFloat(NULL)); 
    // plot->rosenbrock->setMaxZ(widget.fmax->text().toFloat(NULL));


    qDebug() << "ok " << widget.Funkcja->text().toAscii().data();
    plot3d->rosenbrock->parser.SetExpr(widget.Funkcja->text().toAscii().data());

    plot3d->setScale(
            QVariant(widget.scale_x->text()).toFloat(NULL),
            QVariant(widget.scale_y->text()).toFloat(NULL),
            QVariant(widget.scale_f->text()).toFloat(NULL));

    plot3d->setRotation(30, 0, 15);
    pso->czi = QVariant(widget.czi->text()).toFloat(NULL);
    pso->w = QVariant(widget.w->text()).toFloat(NULL);

    pso->maximize = false;

    pso->parser.SetExpr(widget.Funkcja->text().toAscii().data());

    pso->xmin = QVariant(widget.xmin->text()).toFloat(NULL);
    pso->xmax = QVariant(widget.xmax->text()).toFloat(NULL);
    pso->ymin = QVariant(widget.ymin->text()).toFloat(NULL);
    pso->ymax = QVariant(widget.ymax->text()).toFloat(NULL);

    pso->vmax = 100.0;
    pso->c_p = 2.8;
    pso->c_g = 1.3;

    pso->x_width = 10.0;
    pso->y_width = 10.0;




    //    pso->fitness_gbest = pso->populacja[0]->fitness;
    //
    //    pso->gbest_pos[0] = pso->populacja[0]->pbest_pos[0];
    //    pso->gbest_pos[1] = pso->populacja[0]->pbest_pos[1];
    //
    //    plot3d->data_wek.clear();
    //
    //    for (int i = 0; i < pso->populacja.size(); i++) {
    //
    //        // plot->data_wek.push_back(new Point3d(pso->particles_vec[i]->x_pos[0],pso->particles_vec[i]->x_pos[1],pso->particles_vec[i]->fitness));
    //
    //    }
    //
    //
    //
    //
    //
    //
    //    plot3d->rosenbrock->create();
    //
    //    for (unsigned i = 0; i != plot3d->coordinates()->axes.size(); ++i) {
    //        plot3d->coordinates()->axes[i].setMajors(7);
    //        plot3d->coordinates()->axes[i].setMinors(4);
    //    }
    //
    //
    //    plot3d->coordinates()->axes[X1].setLabelString("x-axis");
    //    plot3d->coordinates()->axes[Y1].setLabelString("y-axis");
    //    plot3d->coordinates()->axes[Z1].setLabelString("f(x,y)"); // Omega - see http://www.unicode.org/charts/
    //
    //    plot3d->setCoordinateStyle(BOX);
    //
    //    plot3d->updateData();
    //    plot3d->updateGL();
}

void Forma::Iteruj() {

    int il_it = QVariant(widget.iteracje->text()).toInt(NULL);


    if (widget.czy_maksimum->isChecked()) {
        pso->maximize = true;
    } else {
        pso->maximize = false;
    }


    float offset_x = dane.size();
    for (int i = 0; i < il_it; i++) {


        QString cos1, cos2, cos3, cos4, cos5, cos6;

        pso->c_p = 2.5 - 2.0 * (float) i / (float) il_it;
        pso->c_g = 2.0 * (float) i / (float) il_it + 0.5;

        widget.Debug->append("Iteracja : " + QVariant(i).toString() +
                " \n\tglobal maks = " + cos1.sprintf("%.3f", pso->fitness_gbest) + "\tx = " + cos2.sprintf("%.3f", pso->gbest_pos[0]) + "\ty = " + cos3.sprintf("%.3f", pso->gbest_pos[1])
                + "\tc_g = " + cos5.sprintf("%2.3f", pso->c_g) + "\t\tc_p = " + cos6.sprintf("%2.3f", pso->c_p));


        //x[i]=i;
        // y[i]=pso->fitness_gbest;
        dane.push_back(QPointF(offset_x + (float) i, pso->fitness_gbest));
        plot3d->data_wek.clear();
        pso->Iteruj();
        // qDebug() << "183";






        Wykres();

    }

    //qDebug() << "rozmiar dane " << dane.size() << "\n";

    // dane->push_back(QPointF(1.0,2.0));

    //  curve1->setData();
    curve1->setSamples(dane);

    //curve1->
    //setRawSamples(x,y,il_it);
    //plot2d->
    plot2d->replot();

}

void Forma::Resetuj() {

    widget.Debug->clear();
    dane.clear();
    plot3d->data_wek.clear();
    pso->Inicjuj();
    Wykres();
}

void Forma::Zmiana_funkcji() {
    switch (widget.Funkcje->currentIndex()) {
        case 0://Rastrigin
            widget.Funkcja->setText(QString("x*x-10*cos(2*_pi*x)+10+y*y-10*cos(2*_pi*y)"));
            widget.xmin->setText(QString("-6"));
            widget.xmax->setText(QString("6"));
            widget.ymin->setText(QString("-6"));
            widget.ymax->setText(QString("6"));
            widget.fmax->setText(QString("120"));
            break;
        case 1://Alpine
            widget.Funkcja->setText(QString("2.808*2.808-sin(x)*sin(y)*sqrt(x*y)"));
            widget.xmin->setText(QString("0"));
            widget.xmax->setText(QString("10"));
            widget.ymin->setText(QString("0"));
            widget.ymax->setText(QString("10"));
            widget.fmax->setText(QString("15"));
            break;
        case 2://Rosenbrock
            widget.Funkcja->setText(QString("abs((1-x)*(1-x)+100*(y-x*x)*(y-x*x))"));
            widget.xmin->setText(QString("-2"));
            widget.xmax->setText(QString("2"));
            widget.ymin->setText(QString("-2"));
            widget.ymax->setText(QString("2"));
            widget.fmax->setText(QString("4000"));
            break;
        case 3://cos(3*x*y)
            widget.Funkcja->setText(QString("cos(3*x*y)"));
            widget.xmin->setText(QString("-5"));
            widget.xmax->setText(QString("5"));
            widget.ymin->setText(QString("-5"));
            widget.ymax->setText(QString("5"));
            widget.fmax->setText(QString("2"));
            break;



    }
    Rysuj();


}

void Forma::Suwak_pionowy() {

    // qDebug()<<"suwak pionowy";
    plot3d->setRotation(widget.verticalScrollBar->value() - 180 + 30, 0, widget.horizontalScrollBar->value() - 180 + 15);


}

void Forma::Suwak_poziomy() {

    //qDebug()<<"suwak poziomy";
    plot3d->setRotation(widget.verticalScrollBar->value() - 180 + 30, 0, widget.horizontalScrollBar->value() - 180 + 15);



}

void Forma::Cube() {
    double x, y, f;
    x = pso->xmax - pso->xmin;
    y = pso->ymax - pso->ymin;
    f = QVariant(widget.fmax->text()).toFloat(NULL) - QVariant(widget.fmin->text()).toFloat(NULL);



    if (x >= y && x >= f) {

        plot3d->setScale(1, x / y, x / f);
    } else if (y >= x && y >= f) {

        plot3d->setScale(y / x, 1, y / f);

    } else if (f >= x && f >= y) {

        plot3d->setScale(f / x, f / y, 1);
    }

}

void Forma::Wykres() {
    qDebug() << "wykres\n";

    for (int i = 0; i < pso->populacja.size(); i++) {

        //  plot3d->data_wek.push_back(new Point3d(pso->populacja[i]->x[0], pso->populacja[i]->x[1], pso->populacja[i]->fitness));

    }




    //    for (float i = -2; i < 2; i += 0.2) {
    //
    //        for (float j = -2; j < 2; j += 0.2) {
    //
    //            plot->rosenbrock->xVal = i;
    //            plot->rosenbrock->yVal = j;
    //            plot->data_wek.push_back(new Point3d(i, j, plot->rosenbrock->parser.Eval()));
    //
    //        }
    //
    //    }

    // plot->rosenbrock->create();
    //   plot3d->updateData();
    //   plot3d->updateGL();




}

void Forma::Wireframe() {
    plot3d->setPlotStyle(WIREFRAME);

    Rysuj();


}

void Forma::Dodaj_funkcje() {
    // widget.lista_funkcji->
    qDebug() << "w dodaj funkcje";
    qDebug() << "row count " << widget.lista_funkcji->rowCount();
    // qDebug()<<"text "<<widget.lista_funkcji->item(0, 0)->text();
    int row = widget.lista_funkcji->rowCount();
    widget.lista_funkcji->insertRow(row);
    QTableWidgetItem *item0 = new QTableWidgetItem;
    //    QTableWidgetItem *item1 = new QTableWidgetItem;
    //    QTableWidgetItem *item2 = new QTableWidgetItem;
    QButtonGroup* grupa = new QButtonGroup();
    QRadioButton* radio1 = new QRadioButton();
    QRadioButton* radio2 = new QRadioButton();
    grupa->addButton(radio1);
    grupa->addButton(radio2);
    radio1->setChecked(true);
    //    // item0->setTextAlignment(Qt::AlignRight | Qt::AlignVCenter);
    widget.lista_funkcji->setItem(row, 0, item0);
    // widget.lista_funkcji->setItem(row, 1, item1);
    //  widget.lista_funkcji->setItem(row, 2, item2);
    widget.lista_funkcji->setCellWidget(row, 1, radio1);
    widget.lista_funkcji->setCellWidget(row, 2, radio2);
    //widget.lista_funkcji->item(row, 0)->setText(QString("lol"));
}

void Forma::Usun_funkcje() {
    qDebug() << "w usun funkcje";
    int i = -1;
    for (short s = 0; s < widget.lista_funkcji->rowCount(); s++) {
        if (widget.lista_funkcji->item(s, 0)->isSelected()) {
            i = s;
        }
    }

    if (i >= 0) widget.lista_funkcji->removeRow(i);


}

void Forma::Dodaj_wszystkie_funkcje() {
    problem = new Problem();
    problem->tab_minmax = new bool[widget.lista_funkcji->rowCount()];
    problem->cos = 666;
    qDebug() << "ilosc funkcji " << widget.lista_funkcji->rowCount() << "\n";
    for (int i = 0; i < widget.lista_funkcji->rowCount(); i++) {
        qDebug() << widget.lista_funkcji->item(i, 0)->text().toAscii().data() << " " << widget.lista_funkcji->item(i, 0)->text().length() << "\n";
        if (widget.lista_funkcji->item(i, 0)->text().length() == 0) {
            showWarning("Nie podano funkcji !!!");
            break;
        }
        qDebug() << "dodaje funkcje numer " << i;
        qDebug() << widget.lista_funkcji->item(i, 0)->text().toAscii().data();
        problem->funkcje.push_back(new mu::Parser());
        problem->funkcje[i]->SetVarFactory(&(problem->CCallback), problem);
        problem->funkcje[i]->SetExpr(widget.lista_funkcji->item(i, 0)->text().toAscii().data());
        try {

            problem->funkcje[i]->Eval();

        } catch (mu::Parser::exception_type &e) {
            qWarning() << "Message:  " << e.GetMsg().c_str() << "\n";
            qWarning() << "Formula:  " << e.GetExpr().c_str() << "\n";
            qWarning() << "Token:    " << e.GetToken().c_str() << "\n";
            qWarning() << "Position: " << e.GetPos() << "\n";
            qWarning() << "Errc:     " << e.GetCode() << "\n";


            showWarning("Funkcja " + QString::number(i + 1) + " jest niepoprawna");

            return;


        }


        if (((QRadioButton*) widget.lista_funkcji->cellWidget(i, 1))->isChecked())//oznacza minimalizacje
        {

            problem->tab_minmax[i] = false; //min

            qDebug() << "\ntab_minmax " << i << " = false\n";
        } else {
            problem->tab_minmax[i] = true; //max
            qDebug() << "\ntab_minmax " << i << " = true\n";
        }
        //funkcje[i]->GetUsedVar()
    }


    //wypelniam tabele ze zmiennymi

    for (int i = 0; i < problem->zmienne.size(); i++) {

        widget.lista_zmiennych->insertRow(i);
        QTableWidgetItem *item0 = new QTableWidgetItem;
        widget.lista_zmiennych->setItem(i, 0, item0);
        QTableWidgetItem *item1 = new QTableWidgetItem;
        widget.lista_zmiennych->setItem(i, 1, item1);
        QTableWidgetItem *item2 = new QTableWidgetItem;
        widget.lista_zmiennych->setItem(i, 2, item2);
        // widget.lista_funkcji->setItem(row, 1, item1);
        //  widget.lista_funkcji->setItem(row, 2, item2);
        widget.lista_zmiennych->item(i, 0)->setText(problem->zmienne[i]->nazwa.c_str());
        widget.lista_zmiennych->item(i, 1)->setText("-100");
        widget.lista_zmiennych->item(i, 2)->setText("100");
        //widget.lista_funkcji->setCellWidget(row, 1, radio1);
        //widget.lista_funkcji->setCellWidget(row, 2, radio2);


    }




    for (unsigned int i = 0; i < problem->zmienne.size(); i++) {

        problem->zmienne[i]->zmienna = 1.0;

    }



    //sprawdzenie poprawnosci losowania metoda ruletki

    //    int* tab=new int[pso->hiperkostki.size()];
    //    memset(tab,0,pso->hiperkostki.size()*sizeof(int));
    //    int tmp;
    //    for (int i = 0; i < 100; i++) {
    //        tmp=pso->losuj_kostke_ruletka();
    //        tab[tmp]++;
    //        qDebug()<<"h_ind rand= "<<tmp<<"\n";
    //
    //
    //    }
    //    
    //    for (int i = 0; i < pso->hiperkostki.size(); i++) {
    //        qDebug()<<"il wyl "<<i<<" rowna sie "<<tab[i]<<"\n";
    //
    //
    //    }









    //    for (int i = 0; i < problem->funkcje.size(); i++) {
    //       qDebug()<<"wartosc funkcji "<<i<<" wynosi "<< problem->funkcje[i]->Eval()<<"\n";
    //        
    //
    //
    //    }






}

void Forma::Dodaj_ograniczenie() {
    // widget.lista_funkcji->
    qDebug() << "w dodaj ograniczenie";
    qDebug() << "row count " << widget.lista_ograniczen->rowCount();
    // qDebug()<<"text "<<widget.lista_funkcji->item(0, 0)->text();
    int row = widget.lista_ograniczen->rowCount();
    widget.lista_ograniczen->insertRow(row);
    QTableWidgetItem *item0 = new QTableWidgetItem();
    QComboBox *item1 = new QComboBox();
    QStringList rodz_ograniczen;
    rodz_ograniczen << "<" << "<=" << "=" << ">=" << ">";
    item1->addItems(rodz_ograniczen);
    item1->setCurrentIndex(2);
    QTableWidgetItem *item2 = new QTableWidgetItem();
    widget.lista_ograniczen->setItem(row, 0, item0);
    widget.lista_ograniczen->setCellWidget(row, 1, item1);
    widget.lista_ograniczen->setItem(row, 2, item2);
    // widget.lista_funkcji->setItem(row, 1, item1);
    //  widget.lista_funkcji->setItem(row, 2, item2);


    //widget.lista_funkcji->item(row, 0)->setText(QString("lol"));


}

void Forma::Usun_ograniczenie() {
    qDebug() << "w usun funkcje";
    int i = -1;
    for (short s = 0; s < widget.lista_ograniczen->rowCount(); s++) {
        if (widget.lista_ograniczen->item(s, 0)->isSelected()) {
            i = s;
        }
    }

    if (i >= 0) widget.lista_ograniczen->removeRow(i);


}

void Forma::Dodaj_zakresy_zmiennych() {
    bool ok;
    for (int ind_zmiennych = 0; ind_zmiennych < problem->zmienne.size(); ind_zmiennych++) {
        problem->zmienne[ind_zmiennych]->min = widget.lista_zmiennych->item(ind_zmiennych, 1)->text().toDouble(&ok);
        if (!ok) {
            showWarning("Blad konwersji minimalnej wartosci dla zmiennej o nazwie " + QString(problem->zmienne[ind_zmiennych]->nazwa.c_str()));
            flaga_bledu = true;
            return;

        }
        problem->zmienne[ind_zmiennych]->max = widget.lista_zmiennych->item(ind_zmiennych, 2)->text().toDouble(&ok);
        if (!ok) {
            showWarning("Blad konwersji maksymalnej wartosci dla zmiennej o nazwie " + QString(problem->zmienne[ind_zmiennych]->nazwa.c_str()));
            flaga_bledu = true;
            return;

        }
        if (problem->zmienne[ind_zmiennych]->min >= problem->zmienne[ind_zmiennych]->max) {
            showWarning("Wartość minimalna nie moze być >= wartosci maksymalnej !!!");
            flaga_bledu = true;
            return;


        }

    }





}

void Forma::Dodaj_wszystkie_ograniczenia() {
    for (int i = 0; i < widget.lista_ograniczen->rowCount(); i++) {
        Parser* parser0 = new mu::Parser();
        parser0->SetExpr(widget.lista_ograniczen->item(i, 0)->text().toAscii().data());
        parser0->SetVarFactory(&(problem->CCallback2), problem);
        try {

            parser0->Eval();

        } catch (mu::Parser::exception_type &e) {
            qWarning() << "Message:  " << e.GetMsg().c_str() << "\n";
            qWarning() << "Formula:  " << e.GetExpr().c_str() << "\n";
            qWarning() << "Token:    " << e.GetToken().c_str() << "\n";
            qWarning() << "Position: " << e.GetPos() << "\n";
            qWarning() << "Errc:     " << e.GetCode() << "\n";

            showWarning("Lewa strona ograniczenia " + QString::number(i + 1) + " jest niepoprawna !!!");
            return;
        }
        Parser* parser1 = new mu::Parser();
        parser1->SetExpr(widget.lista_ograniczen->item(i, 2)->text().toAscii().data());
        parser1->SetVarFactory(&(problem->CCallback2), problem);



        try {

            parser1->Eval();

        } catch (mu::Parser::exception_type &e) {
            qWarning() << "Message:  " << e.GetMsg().c_str() << "\n";
            qWarning() << "Formula:  " << e.GetExpr().c_str() << "\n";
            qWarning() << "Token:    " << e.GetToken().c_str() << "\n";
            qWarning() << "Position: " << e.GetPos() << "\n";
            qWarning() << "Errc:     " << e.GetCode() << "\n";

            showWarning("Prawa strona ograniczenia " + QString::number(i + 1) + " jest niepoprawna !!!");
            return;
        }



        qDebug() << "wybrany typ ograniczenia " << ((QComboBox*) widget.lista_ograniczen->cellWidget(i, 1))->currentIndex() << "\n";



        problem->ograniczenia.push_back(new Ograniczenie(parser0, ((QComboBox*) widget.lista_ograniczen->cellWidget(i, 1))->currentIndex(), parser1));


    }





}

void Forma::aktualizuj_wykres_przystosowania() {

    CurveData *data_dom = static_cast<CurveData *> (points_dom->data()); //zeby moc dodawac punkty na wykresie zdominowane i niezdominowane
    //  data->append(point);
    CurveData *data_nondom = static_cast<CurveData *> (points_nondom->data());
    //  data->append(point);


    data_dom->clear();
    data_nondom->clear();

    for (int i = 0; i < pso->populacja.size(); i++) {


        if (pso->populacja[i]->zdominowana) {
            data_dom->append(QPointF(pso->populacja[i]->fitness[0], pso->populacja[i]->fitness[1]));

        }


    }

    for (int i = 0; i < pso->repozytorium.size(); i++) {


        data_nondom->append(QPointF(pso->repozytorium[i]->fitness[0], pso->repozytorium[i]->fitness[1]));



        qDebug() << "i " << i << " : " << pso->repozytorium[i]->fitness[0] << " " << pso->repozytorium[i]->fitness[1] << " " << "\n";
    }


    qDebug() << "il nondom " << data_nondom->size() << "\n";

    plot2d->replot();


}

void Forma::Inicjalizuj() {
    pso = new MOPSO(widget.populacja->text().toInt(NULL, 10), problem);

    pso->vmax = 100.0;

    pso->Inicjuj();


    

    //aktualizuj_wykres_przystosowania();

    // d_directPainter->drawSeries(points_dom, 
    //      data_dom->size() - 1, data_dom->size() - 1);
    //d_directPainter->drawSeries(points_nondom, 
    //    data_nondom->size() - 1, data_nondom->size() - 1);
    //wyswietlamy populacje na wykresie funkcji celu



    pso->wyswietl_repozytorium();
    pso->wyswietl_populacje();

    aktualizuj_wykres_przystosowania();

    qDebug() << "Generuje kostki\n";
    pso->generuj_kostki();


}

void Forma::Iteruj_raz() {

    // qDebug()<<"--------------------------generacja "<<i<<"\n";



    qDebug() << "Aktualizuje predkosci\n";
    pso->aktualizuj_predkosci();

    //  pso->wyswietl_populacje();
    qDebug() << "Aktualizuje pozycje\n";
    pso->aktualizuj_pozycje();

    qDebug() << "Aktualizuje wartosci\n";
    pso->aktualizuj_wartosci();

    qDebug()<<"Mutuje\n";
    pso->mutuj(pso->max_iter,pso->num_iter,0.5);
    pso->num_iter++;
    
    qDebug() << "Sprawdzam zdominowanie\n";
    pso->sprawdz_zdominowanie();

    qDebug() << "Generuje kostki\n";
    pso->generuj_kostki();

    qDebug() << "Aktualizuje repozytorium\n";
    pso->aktualizuj_repozytorium();

    qDebug() << "Aktualizuje pbest\n";
    pso->aktualizuj_pbest();

    //  pso->wyswietl_populacje();
    //  pso->wyswietl_repozytorium();

    aktualizuj_wykres_przystosowania();

}

void Forma::createActions() {

    newAct = new QAction(tr("&New"), this);
    newAct->setShortcuts(QKeySequence::New);
    newAct->setStatusTip(tr("Create a new file"));
    connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));


    openAct = new QAction(tr("&Open..."), this);
    openAct->setShortcuts(QKeySequence::Open);
    openAct->setStatusTip(tr("Open an existing file"));
    connect(openAct, SIGNAL(triggered()), this, SLOT(open()));


    saveAct = new QAction(tr("&Save"), this);
    saveAct->setShortcuts(QKeySequence::Save);
    saveAct->setStatusTip(tr("Save the document to disk"));
    connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));



    exitAct = new QAction(tr("E&xit"), this);
    exitAct->setShortcuts(QKeySequence::Quit);
    exitAct->setStatusTip(tr("Exit the application"));
    connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));

    settingsAct = new QAction(tr("Ustawienia"), this);

    settingsAct->setStatusTip(tr("Exit the application"));
    connect(settingsAct, SIGNAL(triggered()), this, SLOT(settings()));


}

void Forma::createMenus() {

    fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(newAct);

    //    fileMenu->addAction(openAct);
    //
    fileMenu->addAction(saveAct);
    fileMenu->addAction(openAct);
    //
    //
    fileMenu->addSeparator();
    //
    fileMenu->addAction(exitAct);


    settingsMenu = menuBar()->addMenu(tr("&Settings"));
    settingsMenu->addAction(settingsAct);


}

void Forma::newFile() {
    // infoLabel->setText(tr("Invoked <b>File|New</b>"));


}

void Forma::open() {
    QFileDialog *dialog = new QFileDialog();

    QString str = QDir::currentPath();
    QString filename = dialog->getOpenFileName(this, tr("Open File"), str +
            "/zapiane/problem.prob",
            tr("Images (*.prob)"));

    qDebug("990\n");
    wczytajProblem(filename);
}

void Forma::save() {
    QFileDialog *dialog = new QFileDialog();

    QString str = QDir::currentPath();
    QString filename = dialog->getSaveFileName(this, tr("Save File"), str +
            "/zapiane/problem.prob",
            tr("Images (*.prob)"));


    zapiszProblem(filename);

    // graph->save(filename.remove(str + "/"));
    // infoLabel->setText(tr("Invoked <b>File|Save</b>"));
}

void Forma::exit() {


}

void Forma::settings() {


}

bool Forma::wczytajProblem(QString nazwa_pliku) {

    qDebug() << "wczytuje";

    QString nazwa, kolor;
    int prio, param;
    //  tab_funkcji = new QVector<Jednostka>[4];

    QFile file(nazwa_pliku);
    if (!file.open(QIODevice::ReadOnly)) {
        qDebug() << "Cannot open file for writing: "
                << qPrintable(file.errorString()) << endl;
        return false;
    }
    QTextStream in(&file);
    QString co;
    int il;
    double liczba;
    qDebug() << "wczytuje funkcje\n";
    in >> co;
    in >> il;
    for (int i = widget.lista_funkcji->rowCount() - 1; i >= 0; i--)widget.lista_funkcji->removeRow(i);

    for (int i = 0; i < il; i++) {
        qDebug() << i << "\n";
        widget.lista_funkcji->insertRow(i);
        qDebug() << "po insert" << "\n";
        in >> co;
        qDebug() << co << "\n";
        QTableWidgetItem *item0 = new QTableWidgetItem;

        DINFO
        QButtonGroup* grupa = new QButtonGroup();
        QRadioButton* radio1 = new QRadioButton();
        QRadioButton* radio2 = new QRadioButton();
        grupa->addButton(radio1);
        grupa->addButton(radio2);
        radio1->setChecked(true);

        widget.lista_funkcji->setItem(i, 0, item0);
        widget.lista_funkcji->setCellWidget(i, 1, radio1);
        widget.lista_funkcji->setCellWidget(i, 2, radio2);

        widget.lista_funkcji->item(i, 0)->setText(co);
        DINFO

        in >> co;
        DINFO
        qDebug() << co << "\n";
        DINFO
        if (co.compare("min")) {
            ((QRadioButton*) widget.lista_funkcji->cellWidget(i, 1))->setChecked(true);

        } else {
            ((QRadioButton*) widget.lista_funkcji->cellWidget(i, 1))->setChecked(true);

        }

    }

    //funkcje
    qDebug() << "wczytuje zmienne\n";
    in >> co;
    in >> il;
    for (int i = widget.lista_zmiennych->rowCount() - 1; i >= 0; i--)widget.lista_zmiennych->removeRow(i);

    for (int i = 0; i < il; i++) {
        qDebug() << i << "\n";
        widget.lista_zmiennych->insertRow(i);

        QTableWidgetItem *item0 = new QTableWidgetItem;
        widget.lista_zmiennych->setItem(i, 0, item0);
        QTableWidgetItem *item1 = new QTableWidgetItem;
        widget.lista_zmiennych->setItem(i, 1, item1);
        QTableWidgetItem *item2 = new QTableWidgetItem;
        widget.lista_zmiennych->setItem(i, 2, item2);

        in >> co;
        widget.lista_zmiennych->item(i, 0)->setText(co);

        in >> liczba;

        widget.lista_zmiennych->item(i, 1)->setText(QString::number(liczba));

        in >> liczba;

        widget.lista_zmiennych->item(i, 2)->setText(QString::number(liczba));


    }


    //ograniczenia

    qDebug() << "wczytuje ograniczenia\n";

    in >> co;
    in >> il;
    for (int i = widget.lista_ograniczen->rowCount() - 1; i >= 0; i--)widget.lista_ograniczen->removeRow(i);

    for (int i = 0; i < il; i++) {
        qDebug() << i << "\n";
        widget.lista_ograniczen->insertRow(i);


        QTableWidgetItem *item0 = new QTableWidgetItem();
        QComboBox *item1 = new QComboBox();
        QStringList rodz_ograniczen;
        rodz_ograniczen << "<" << "<=" << "=" << ">=" << ">";
        item1->addItems(rodz_ograniczen);
 
        QTableWidgetItem *item2 = new QTableWidgetItem();
        widget.lista_ograniczen->setItem(i, 0, item0);
        widget.lista_ograniczen->setCellWidget(i, 1, item1);
        widget.lista_ograniczen->setItem(i, 2, item2);



        in >> co;
        widget.lista_ograniczen->item(i, 0)->setText(co);

        in >> liczba;

        ((QComboBox*) widget.lista_ograniczen->cellWidget(i, 1))->setCurrentIndex((int) liczba);

        in >> co;

        widget.lista_ograniczen->item(i, 2)->setText(co);


    }



    // kolor_liczb=kolor;

    //    while (!in.atEnd()) {
    //
    //        in >> nazwa;
    //        qDebug() << nazwa;
    //        in >> prio;
    //        qDebug() << " " << prio;
    //        in >> param;
    //        qDebug() << " " << param ;
    //        in >> kolor;
    //        qDebug() << " " << kolor << "\n";
    //
    //        if (nazwa != QString("")) {
    //           // tab_funkcji[prio - 1].push_back(Jednostka(nazwa, prio, param, QColor(kolor)));
    //
    //        }
    //    }

    file.close();

    return true;
}

bool Forma::zapiszProblem(QString nazwa_pliku) {
    QFile file(nazwa_pliku);
    if (!file.open(QIODevice::WriteOnly)) {
        //qDebug() << "Cannot open file for writing: "
        //     << qPrintable(file.errorString()) << endl;
        return false;
    }
    QTextStream out(&file);



    // tab_funkcji[table->item(row, 1)->data(0).toInt(NULL)]

    out << "[Funkcje]\n";
    // widget.lista_funkcji.si
    out << widget.lista_funkcji->rowCount() << "\n";
    for (int i = 0; i < widget.lista_funkcji->rowCount(); i++) {

        out << widget.lista_funkcji->item(i, 0)->text().toAscii().data();
        if (((QRadioButton*) widget.lista_funkcji->cellWidget(i, 1))->isChecked()) {
            out << " " << "min" << "\n";

        } else {
            out << " " << "max" << "\n";

        }






    }

    out << "[Zmienne]\n";
    out << widget.lista_zmiennych->rowCount() << "\n";
    for (int i = 0; i < widget.lista_zmiennych->rowCount(); i++) {

        out << widget.lista_zmiennych->item(i, 0)->text().toAscii().data() << " "
                << widget.lista_zmiennych->item(i, 1)->text().toAscii().data() << " "
                << widget.lista_zmiennych->item(i, 2)->text().toAscii().data() << "\n";






    }

    out << "[Ograniczenia]\n";
    out << widget.lista_ograniczen->rowCount() << "\n";
    for (int i = 0; i < widget.lista_ograniczen->rowCount(); i++) {

        out << widget.lista_ograniczen->item(i, 0)->text().toAscii().data() << " "
                << ((QComboBox*) widget.lista_ograniczen->cellWidget(i, 1))->currentIndex() << " "
                << widget.lista_ograniczen->item(i, 2)->text().toAscii().data() << "\n";






    }

    file.close();


    return true;

}